package com.base.cn.platform.os.controller.course.cou.buy;

import com.base.cn.platform.os.common.controller.BaseController;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.course.CourseType;
import com.base.cn.platform.os.common.utils.order.OrderStatus;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.course.cou.Course;
import com.base.cn.platform.os.entity.course.cou.buy.CourseBuyRecord;
import com.base.cn.platform.os.entity.course.cou.buy.CourseBuyRecordExpand;
import com.base.cn.platform.os.entity.course.cou.packageCou.PackageCourse;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyRecordBiz;
import com.base.cn.platform.os.service.course.cou.record.CoursePlayRecordBiz;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 课程购买记录Controller接口
 *
 * @author s.li
 * @create 2018-05-17-16:58
 */
@RestController
@RequestMapping("/course")
public class CourseBuyRecordController extends BaseController {

    @Autowired
    private CourseBuyRecordBiz courseBuyRecordBiz;
    @Autowired
    private CoursePlayRecordBiz coursePlayRecordBiz;


    /**
     * 获取用户课程数据
     * @return  Map<String,Integer>
     */
    @RequestMapping("/getUserCourseNum")
    public Map<String,Integer> getUserCourseNum(@RequestParam("userId") BigDecimal userId){
        Map<String,Integer> numMap = new HashMap<>();
        //用户购买量（状态正常的）
        int buyCourseNum = courseBuyRecordBiz.count(" userId="+userId +" and courseStatus='"+ OrderStatus.SUCCESS+"' and validTime >= '"+ DateUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss")+"'").intValue();
        numMap.put("buyCourseNum",buyCourseNum);
        return numMap;
    }

    /**
     * 检测用户是否购买过该课程
     * @param userId
     * @param courseId
     * @return CourseBuyRecord 返回null则未购买过
     */
    @RequestMapping("/checkUserBuyCourse")
    public CourseBuyRecord checkUserBuyCourse(@RequestParam("userId") BigDecimal userId,
                                      @RequestParam("courseId") BigDecimal courseId){
        return courseBuyRecordBiz.checkUserBuyCourse(userId,courseId);
    }

    /**
     * 修改课程过期时间
     * @param detailsId
     * @param validTime
     */
    @RequestMapping("/updateCourseBuyRecordValidTime")
    public Map<String,Object> updateCourseBuyRecordValidTime(@RequestParam("detailsId") BigDecimal detailsId,
                                                             @RequestParam("validTime") String validTime){
        try {
            Date time = DateUtils.parseDate(validTime,new String[]{"yyyy-MM-dd HH:mm:ss"});
            courseBuyRecordBiz.updateCourseBuyRecordValidTime(detailsId,time);
        } catch (ParseException e) {
            logger.error("updateCourseBuyRecordValidTime()--error",e);
            return ResultUtil.ERROR("时间转换错误，修改失败");
        }
        return ResultUtil.SUCCESS("课程购买记录到期时间修改成功");
    }

    /**
     * 保存课程购买记录
     * @param courseBuyRecordList
     */
    @RequestMapping("/createCourseBuyRecord")
    public void createCourseBuyRecord(@RequestBody List<CourseBuyRecord> courseBuyRecordList){
        courseBuyRecordBiz.createCourseBuyRecord(courseBuyRecordList);
    }

    /**
     * 通过流水ID，修改课程购买记录状态
     * @param detailsId 流水ID
     * @param courseStatus  课程状态，SUCCESS可使用，REFUND退费，CLOSE关闭
     * @return Map<String,Object>
     */
    @RequestMapping("/updateRecordCourseStatusByDetailsId")
    public Map<String,Object> updateRecordCourseStatusByDetailsId(@RequestParam("detailsId") BigDecimal detailsId,
                                                           @RequestParam("courseStatus") String courseStatus){
        courseBuyRecordBiz.updateRecordCourseStatusByDetailsId(detailsId,courseStatus);
        return ResultUtil.SUCCESS();
    }

    /**
     * 通过订单ID，修改课程购买记录的状态
     * @param orderId 订单ID
     * @param courseStatus 课程状态，SUCCESS可使用，REFUND退费，CLOSE关闭
     */
    @RequestMapping("/updateRecordCourseStatus")
    public Map<String,Object> updateRecordCourseStatus(BigDecimal orderId,String courseStatus){
        CourseBuyRecord record = new CourseBuyRecord();
        record.setCourseStatus(courseStatus);
        courseBuyRecordBiz.updateByWhereSql(record," orderId="+orderId);
        return ResultUtil.SUCCESS();
    }

    /**
     * 分页查询用户购买记录(查询我的课程)
     * @param courseBuyRecord 查询条件
     * @param currentPage 当前码
     * @param pageSize 页面显示数量
     * @param setCourseData 是否设置课程
     * @param setStudySpeed 是否设置课程学习进度
     * @param setStudySumTime 是否设置总学习时间
     * @param setWeekStudyTime 是否设置一周的学习时间
     * @param setLastStudyCatalog 是否设置最后一个学习的目录
     * @return PageInfo<CourseBuyRecord>
     */
    @RequestMapping("/findCourseBuyRecordPage")
    public PageInfo<CourseBuyRecord> findCourseBuyRecordPage(@RequestBody CourseBuyRecord courseBuyRecord,
                                                             @RequestParam(value = "currentPage",required = false,defaultValue = "1") int currentPage,
                                                             @RequestParam(value = "pageSize",required = false,defaultValue = "10") int pageSize,
                                                             @RequestParam("setCourseData") boolean setCourseData,
                                                             @RequestParam("setTeacherData") boolean setTeacherData,
                                                             @RequestParam("setProfileData") boolean setProfileData,
                                                             @RequestParam("setStudySpeed") boolean setStudySpeed,
                                                             @RequestParam("setStudySumTime") boolean setStudySumTime,
                                                             @RequestParam("setWeekStudyTime") boolean setWeekStudyTime,
                                                             @RequestParam("setLastStudyCatalog") boolean setLastStudyCatalog){
        Pagination page = new Pagination();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
        return courseBuyRecordBiz.findCourseBuyRecordPage(courseBuyRecord,page,setCourseData,
                setTeacherData,setProfileData,setStudySpeed,setStudySumTime,setWeekStudyTime,setLastStudyCatalog);
    }

    /**
     * 查询课程购买记录（不分页）
     * @param courseBuyRecord 查询条件
     * @param setCourseData 是否设置课程
     * @return
     */
    @RequestMapping("/findCourseBuyRecordList")
    public List<CourseBuyRecord> findCourseBuyRecordList(@RequestBody CourseBuyRecord courseBuyRecord,
                                                         @RequestParam("setCourseData") boolean setCourseData){
        return courseBuyRecordBiz.findCourseBuyRecordList(courseBuyRecord, setCourseData);
    }

    /**
     * 查询课程购买记录Map
     * @param courseBuyRecord 查询条件
     * @param setCourseData 是否设置课程
     * @return Map<BigDecimal,List<CourseBuyRecord>>
     */
    @RequestMapping("/findCourseBuyRecordMap")
    public Map<BigDecimal,List<CourseBuyRecord>> findCourseBuyRecordMap(@RequestBody CourseBuyRecord courseBuyRecord,
                                                                        @RequestParam("setCourseData") boolean setCourseData){
        List<CourseBuyRecord> courseBuyRecordList =courseBuyRecordBiz.findCourseBuyRecordList(courseBuyRecord, setCourseData);
        if(ObjectUtils.isNotEmpty(courseBuyRecordList)){
            return courseBuyRecordList.stream().collect(Collectors.groupingBy(e->e.getCourseId()));
        }
        return null;
    }

    /**
     * 获取用户的购买列表，一般用于验证数据
     * @param courseBuyRecord 查询条件对象
     * @param setCourseData 是否设置课程数据
     * @return List<CourseBuyRecord>
     */
    @RequestMapping("/findCourseBuyRecordByUserId")
    public List<CourseBuyRecord> findCourseBuyRecordByUserId(@RequestBody CourseBuyRecord courseBuyRecord,
                                                             @RequestParam("setCourseData") boolean setCourseData){
        return courseBuyRecordBiz.findCourseBuyRecordByUserId(courseBuyRecord,setCourseData);
    }

    /**
     * 获取播放的购买记录
     * @param id 记录ID
     * @return CourseBuyRecord
     */
    @RequestMapping("/findPlayCourseBuyRecordById")
    public CourseBuyRecord findPlayCourseBuyRecordById(@RequestParam("id") BigDecimal id){
        return courseBuyRecordBiz.findPlayCourseBuyRecordById(id);
    }

    /**
     * 通过ID获取购买记录
     * @param id 记录ID
     * @param userId 用户ID
     * @param setCourseData 是否设置套餐数据
     * @param setPackageCourseData 是否设置套餐下课程课程数据（套餐类型的记录才起作用）
     * @return CourseBuyRecord
     */
    @RequestMapping("/findCourseBuyRecordById")
    public CourseBuyRecord findCourseBuyRecordById(@RequestParam("id") BigDecimal id,
                                                   @RequestParam("userId") BigDecimal userId,
                                                   @RequestParam("setCourseData") boolean setCourseData,
                                                   @RequestParam("setPackageCourseData") boolean setPackageCourseData){
        return courseBuyRecordBiz.findCourseBuyRecordById(id,userId,setCourseData,setPackageCourseData);
    }

    /**
     * 通过ID获取套餐的激活数据
     * @param id 记录ID
     * @param userId 用户ID
     * @return CourseBuyRecord
     */
    @RequestMapping("/findPackageActivationById")
    public Map<String,Object> findPackageActivationById(@RequestParam("id") BigDecimal id,
                                                   @RequestParam("userId") BigDecimal userId){
        CourseBuyRecord record = courseBuyRecordBiz.findCourseBuyRecordById(id,userId,true,true);
        if(record==null){
            return ResultUtil.ERROR("套餐激不存在");
        }
        if(!record.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())){
            return ResultUtil.ERROR("数据错误");
        }
        if(record.getStatus().intValue() != 0){
            return ResultUtil.ERROR("该套餐记录已激活");
        }
        return ResultUtil.SUCCESS("查询成功",record);
    }

    /***
     * 激活套餐
     * @param userId 用户ID
     * @param recordId 购买记录ID
     * @param courseIds 购买套餐下要激活的课程ID串
     * @return Map<String,Object>
     */
    @RequestMapping("/activationPackage")
    public Map<String,Object> activationPackage(@RequestParam("userId") BigDecimal userId,
                                                @RequestParam("recordId") BigDecimal recordId,
                                                @RequestParam("courseIds") String courseIds){
        CourseBuyRecord record = courseBuyRecordBiz.findCourseBuyRecordById(recordId,userId,true,true);
        if(ObjectUtils.isEmpty(record)){
            return ResultUtil.ERROR("套餐购买记录不存在");
        }
        if(!record.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())){
            return ResultUtil.ERROR("数据错误");
        }
        if(record.getStatus().intValue() != 0){
            return ResultUtil.ERROR("该套餐记录已激活");
        }
        if(StringUtils.isEmpty(courseIds)){
            return ResultUtil.ERROR("请选择要激活的课程");
        }

        List<PackageCourse> packageCourseList = record.getCourse().getPackageCourseList();
        Map<BigDecimal,PackageCourse> packageCourseMap = packageCourseList.stream().filter(e->e.getPackageType().intValue()==1).collect(Collectors.toMap(e->e.getCourseId(),e->e));
        String[] arr = StringUtils.subHeadTailString(courseIds,",").split(",");
        for(String str : arr){
            PackageCourse packageCourse = packageCourseMap.get(new BigDecimal(str));
            if(ObjectUtils.isEmpty(packageCourse)){
                return ResultUtil.ERROR("选择的课程不包含在套餐中");
            }
        }
        Map<Integer,List<PackageCourse>> packageCourseListMap = packageCourseList.stream().filter(e->e.getPackageType().intValue()==1).collect(Collectors.groupingBy(e->e.getRequired()));
        //必选列表
        List<PackageCourse> requiredList = packageCourseListMap.get(1);
        if(ObjectUtils.isNotEmpty(requiredList)){
            packageCourseMap = requiredList.stream().collect(Collectors.toMap(e->e.getCourseId(),e->e));
            int index = 0;
            for(String str : arr){
                PackageCourse packageCourse = packageCourseMap.get(new BigDecimal(str));
                if(ObjectUtils.isNotEmpty(packageCourse)){
                    index++;
                }
            }
            if(index != requiredList.size()){
                return ResultUtil.ERROR("选择课程错误，必须课程未全部选择");
            }
        }
        if(record.getCourse().getUseNum().intValue() > 0 && record.getCourse().getUseNum().intValue() != record.getCourse().getCourseNum().intValue()){
            if(arr.length > record.getCourse().getUseNum().intValue()){
                return ResultUtil.ERROR("该套餐最多可选择【"+record.getCourse().getUseNum()+"】个课程");
            }
        }
        courseBuyRecordBiz.activationPackage(record,arr);
        return ResultUtil.SUCCESS("套餐激活成功");
    }

    /**
     * 通过流水ID获取购买记录
     * @param detailsId 记录ID
     * @param setCourseData 是否设置课程数据
     * @return CourseBuyRecord
     */
    @RequestMapping("/findCourseBuyRecordByDetailsId")
    public CourseBuyRecord findCourseBuyRecordByDetailsId(@RequestParam("detailsId") BigDecimal detailsId,
                                                          @RequestParam("setCourseData") boolean setCourseData){
        return courseBuyRecordBiz.findCourseBuyRecordByDetailsId(detailsId,setCourseData);
    }

    /**
     * 更新记录状态，用于套餐手动激活
     * @param id 记录ID
     * @param status 状态，0未激动，1已激活
     * @param courseIds 课程ID串
     */
    @RequestMapping("/updateCourseBuyRecordStatus")
    public Map<String,Object> updateCourseBuyRecordStatus(@RequestParam("id") BigDecimal id,
                                                          @RequestParam("userId") BigDecimal userId,
                                                          @RequestParam("status") int status,
                                                          @RequestParam("courseIds") String courseIds){
        CourseBuyRecord record = courseBuyRecordBiz.findCourseBuyRecordById(id,userId,true,true);
        if(ObjectUtils.isEmpty(record)){
            return ResultUtil.ERROR("套餐课程观看权限记录不存在");
        }
        if(record.getCourse()==null){
            return ResultUtil.ERROR("套餐课程不存在");
        }
        if(record.getStatus().intValue()==1){
            return ResultUtil.ERROR("该套餐记录已激活过，不可重复激活");
        }
        if(!record.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())){
            return ResultUtil.ERROR("该课程不是套餐课程，不需要激活");
        }
        List<PackageCourse> packageCourseList = record.getCourse().getPackageCourseList();
        if(ObjectUtils.isEmpty(packageCourseList)){
            return ResultUtil.ERROR("套餐未绑定课程数据");
        }
        if(record.getUserId().compareTo(userId)!=0 || !DataUtil.idIsNotNull(userId)){
            return ResultUtil.ERROR("数据错误，套餐课程激活失败");
        }
        courseIds = StringUtils.subHeadTailString(courseIds,",");
        if(StringUtils.isEmpty(courseIds)){
            return ResultUtil.ERROR("请选择套餐内课程");
        }
        String[] arr = courseIds.split(",");
        Course course = record.getCourse();
        if(course.getCourseNum().intValue()< arr.length){
            return ResultUtil.ERROR("选择课程数据错误");
        }
        if(course.getUseNum().intValue() < arr.length){
            return ResultUtil.ERROR("套餐下课程最多可选择【"+course.getUseNum()+"】个");
        }
        Map<BigDecimal,PackageCourse> packageCourseMaps = packageCourseList.stream().filter(e->(e.getPackageType().intValue()==1)).collect(Collectors.toMap(e->e.getCourseId(),e->e));
        //通过必选和非必选分组
        Map<Integer,List<PackageCourse>> packageCourseListMaps = packageCourseList.stream().filter(e->(e.getPackageType().intValue()==1)).collect(Collectors.groupingBy(e->e.getRequired()));

        for(String courseId : arr){
            PackageCourse packageCourse = packageCourseMaps.get(new BigDecimal(courseId));
            if(ObjectUtils.isEmpty(packageCourse)){
                return ResultUtil.ERROR("选择的课程不包含在套餐中");
            }
        }
        //必选课程数据
        List<PackageCourse> requiredList = packageCourseListMaps.get(1);
        if(ObjectUtils.isNotEmpty(requiredList)){
            packageCourseMaps = requiredList.stream().filter(e->(e.getPackageType().intValue()==1)).collect(Collectors.toMap(e->e.getCourseId(),e->e));
            for(String courseId : arr){
                BigDecimal key = new BigDecimal(courseId);
                PackageCourse packageCourse = packageCourseMaps.get(key);
                if(ObjectUtils.isNotEmpty(packageCourse)){
                    packageCourseMaps.remove(key);
                }
            }
            if(!packageCourseMaps.isEmpty()){
                return ResultUtil.ERROR("必选课程错误");
            }
        }
        courseBuyRecordBiz.updateCourseBuyRecordStatus(record,status,courseIds);
        return ResultUtil.SUCCESS("激活成功");
    }

    /**
     * 分页查询用户购买记录(查询我的课程,用于前台)
     * @param courseBuyRecord 查询条件
     * @param currentPage 当前码
     * @param pageSize 页面显示数量
     * @param setCourseData 是否设置课程
     * @param setStudySpeed 是否设置课程学习进度
     * @param setStudySumTime 是否设置总学习时间
     * @param setWeekStudyTime 是否设置一周的学习时间
     * @param setLastStudyCatalog 是否设置最后一个学习的目录
     * @return PageInfo<CourseBuyRecord>
     */
    @RequestMapping("/findCourseBuyRecordFrontPage")
    public PageInfo<CourseBuyRecord> findCourseBuyRecordFrontPage(@RequestBody CourseBuyRecord courseBuyRecord,
                                                             @RequestParam(value = "currentPage",required = false,defaultValue = "1") int currentPage,
                                                             @RequestParam(value = "pageSize",required = false,defaultValue = "10") int pageSize,
                                                             @RequestParam("setCourseData") boolean setCourseData,
                                                             @RequestParam("setTeacherData") boolean setTeacherData,
                                                             @RequestParam("setProfileData") boolean setProfileData,
                                                             @RequestParam("setStudySpeed") boolean setStudySpeed,
                                                             @RequestParam("setStudySumTime") boolean setStudySumTime,
                                                             @RequestParam("setWeekStudyTime") boolean setWeekStudyTime,
                                                             @RequestParam("setLastStudyCatalog") boolean setLastStudyCatalog){
        Pagination page = new Pagination();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
        return courseBuyRecordBiz.findCourseBuyRecordFrontPage(courseBuyRecord,page,setCourseData,
                setTeacherData,setProfileData,setStudySpeed,setStudySumTime,setWeekStudyTime,setLastStudyCatalog);
    }


    /**
     * 分页查询用户购买记录(查询我的课程,用于前台)
     * @param courseBuyRecordExpand 查询条件
     * @param currentPage 当前码
     * @param pageSize 页面显示数量
     * @return PageInfo<CourseBuyRecord>
     */
    @RequestMapping("/findCourseBuyRecordLearnPage")
    public PageInfo<CourseBuyRecord> findCourseBuyRecordLearnPage(@RequestBody CourseBuyRecordExpand courseBuyRecordExpand,
                                                                  @RequestParam(value = "currentPage",required = false,defaultValue = "1") int currentPage,
                                                                  @RequestParam(value = "pageSize",required = false,defaultValue = "10") int pageSize){
        Pagination page = new Pagination();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);

        return courseBuyRecordBiz.findCourseBuyRecordLearnPage(courseBuyRecordExpand ,page);
    }

}
